<template>
  <div>
    <div>
      <el-upload
        ref="uploadRef"
        class="flx-align-center"
        :file-list="fileList"
        :multiple="multiple"
        :limit="limit"
        :disabled="disabled"
        :accept="fileType"
        :show-file-list="false"
        :http-request="handleHttpUpload"
        :before-upload="beforeUpload"
        :on-exceed="handleExceed"
      >
        <slot name="upload-btn">
          <div class="upload-content">
            <el-button type="success" :icon="UploadFilled" plain @click="handleClick">
              {{ btnText }}
            </el-button>
          </div>
        </slot>
      </el-upload>
      <!-- 提示 -->
      <div class="upload-tip" v-if="tipShow">
        <slot name="tip">{{ tipComputed }}</slot>
      </div>
    </div>
    <div class="upload-box">
      <slot></slot>
    </div>
  </div>
</template>

<script setup>
import { useI18n } from "vue-i18n";
const { t } = useI18n();
import { UploadFilled } from "@element-plus/icons-vue";
import { ElNotification } from "element-plus";
import { getFileType } from "@/utils/file/assetsFile";

// 组件 Props
const props = defineProps({
  // uploadApiName: { type: Function, required: true }, // 上传接口的函数
  btnText: { type: String, default: "点击上传" }, // 按钮文本
  fileType: { type: String, default: ".pdf, .jpg, .png, .jpeg" },
  // uploadParams: { type: Object, default: () => ({}) }, // 上传参数
  fileSize: { type: Number, default: 60 }, // 最大文件大小 (MB)
  limit: { type: Number, default: Infinity }, // 限制上传数量
  tipShow: { type: Boolean, default: true }, // 是否显示提示信息
  multiple: { type: Boolean, default: true }, // 是否多选
  fileList: { type: Array, default: () => [] }, // 文件列表
  disabled: { type: Boolean, default: false }, // 是否禁用上传
  handleClick: { type: Function, default: () => {} }, // 点击上传按钮自定义事件
});
// const buttonText = computed(() => props.btnText);

// 组件事件
const emit = defineEmits(["upload-success"]);

// 计算上传提示
const tipComputed = computed(() => {
  const tip = props.fileType.replace(/\./g, "").replace(/,/g, "、").toUpperCase();
  return `支持${tip}格式，大小不得超过${props.fileSize}M`;
});

// 记录上传的文件
const uploadLatestFile = ref(null); // 最近上传的文件
const uploadList = ref([]); // 上传的文件列表

const uploadRef = ref(null); // 上传组件的引用
// 校验上传前的文件
function beforeUpload(rawFile) {
  // 获取文件类型
  const extension = getFileType(rawFile.name, 1);
  const fileType = props.fileType.replace(/\./g, ""); // 去掉小数点
  const isAllowedType = fileType.includes(extension);

  if (!isAllowedType) {
    ElNotification({
      title: "温馨提示",
      message: "上传文件格式不正确！",
      type: "warning",
    });
    return false;
  }

  // 判断文件大小
  if (rawFile.size / 1024 / 1024 > props.fileSize) {
    ElNotification({
      title: "温馨提示",
      message: `上传文件大小不能超过 ${props.fileSize}M！`,
      type: "warning",
    });
    return false;
  }
  return true;
}

// 处理超出文件限制
function handleExceed() {
  ElNotification({
    title: "温馨提示",
    message: `超出文件上传最大数量：${props.limit}！`,
    type: "warning",
  });
  return false;
}

// 处理文件上传
async function handleHttpUpload(options) {
  // 触发上传成功事件
  emit("upload-success", options.file);
  // 上传成功后清空文件列表
  await uploadRef.value?.clearFiles();
}

// 组件暴露
defineExpose({
  uploadList,
  uploadLatestFile,
});
</script>

<style lang="scss" scoped>
.upload-content {
  display: flex;
  flex-direction: column;
  margin: 0 10px;
}

.upload-box {
  max-height: 400px;
  overflow: auto;
}

.upload-tip {
  display: flex;
  align-items: center;
  font-size: 12px;
  line-height: 32px;
  color: var(--el-label-color-regular);
}
</style>
